---
title: "Catch Connection Token"
description: ""
icon: "webhook"
---

Before getting started, you must have set up the auth flow through [magic-link or using the embedded snippet](/quick-start).
If you need to understand in depth these concepts, jump to the [magic-link](/recipes/share-magic-link) and [frontend widget](/recipes/embed-catalog) recipes.<br/>

<Info>
  You may need to follow first our [webhook](/webhooks/overview) guide so you
  can understand quickly the next steps.
</Info>
# How to catch connection tokens ?

A `connection_token` is created everytime a user connects an account to your platform.<br/>
It is a field of the [Connection Object](/glossary/connection-object) that Panora sends as a payload data through a webhook when you listen to events tagged as `connection.created`.

<Steps>
    <Step title="Create a webhook endpoint handler to receive event data POST requests.">
        <Note>
            We must listen to `connection.created` event.
        </Note>
    
        <CodeGroup>

        ```javascript Node
        // This example uses Express to receive webhooks
        import express, { Request, Response } from 'express';
        const app = express();
        app.use(express.json());

        // Match the raw body to content type application/json
        // If you are using Express v4 - v4.16 you need to use body-parser, not express, to retrieve the request body
        app.post('/webhook', (request, response) => {
            const event = request.body;

            // Handle the event
            switch (event.type) {
                case 'connection.created':
                    const connectionObject = JSON.parse(event.data);
                    // Then define and call a method to handle the successful connection creation.
                    // handleConnectionCreationSucceeded(connectionObject);
                    break;
                default:
                    console.log(`Unhandled event type ${event.type}`);
            }

            // Return a response to acknowledge receipt of the event
            response.json('Received !');
        });

        app.listen(8000, () => console.log('Running on port 8000'));
        ```

        ```python Python
        import json
        from django.http import HttpResponse

        # Using Django
        @csrf_exempt
        def my_webhook_view(request):
            event = request.body

            # Handle the event
            if event.type == 'connection.created':
                connection_object = event.data
                # Then define and call a method to handle the successful connection creation.
                # handle_connection_creation_succeeded(connection_object)
            else:
                print('Unhandled event type {}'.format(event.type))

            return HttpResponse(status=200)
        ```

        </CodeGroup>
        If you log `event.data`, you'll be able to check that it is a [Connection Object](/glossary/connection-object). Hence, it contains an `id_linked_user`(more info [here](/glossary/linked-account-object)) which is helpful to attach it to your own end-user on your backend/db systems.
    </Step>
    <Step title="Register your endpoint within Panora using the Dashboard or the API.">
        Register the webhook endpoint’s accessible URL using the _Webhooks_ [section](https://app.panora.dev/configuration) or the API so Panora knows where to deliver events.<br/>

        **Webhook URL format** <br/>

        The URL format to register a webhook endpoint is:
        ```
        https://<your-website>/<your-webhook-endpoint>
        ```
        For example, if your domain is `https://mycompanysite.com` and the route to your webhook endpoint is `@app.route('/panora_webhooks', methods=['POST'])`, specify `https://mycompanysite.com/panora_webhooks` as the Endpoint URL. <br/>

        **Add a webhook endpoint** <br/>

        Navigate to the _Configuration_ [section](https://app.panora.dev/configuration) and head to the Webhooks tab. <br/>
            <video
            controls
            className="w-full aspect-video"
            src="/images/webhooks.mp4"
            ></video>

        **Register a webhook endpoint with the Panora API** <br/>

        You can also programmatically create [webhook endpoints](/api-reference/webhook/add-webhook-metadata). <br/>

        The following example creates an endpoint that notifies you when a connection is created.

        <CodeGroup>
        ```shell Curl
        curl --request POST \
             --url https://api.panora.dev/webhooks \
             --header 'x-api-key: <api-key>' \
             --header 'Content-Type: application/json' \
             --data '{
                "url": "https://acme.com/webhook_receiver",
                "description": "Receive Connection Creation Events",
                "scope": [
                    "connection.created"
                ]
             }'
        ```
 
        ```ts Typescript
        import { Panora } from '@panora/sdk';

        const panora = new Panora({ apiKey: process.env.API_KEY});

        const result = await panora.webhooks.create({
            url: "https://acme.com/webhook_receiver",
            description: "Webhook to receive connection events",
            scope: [
                "connection.created",
            ],
        });
        console.log(result);
        ```

        ```python Python
        import os
        from panora_sdk import Panora

        panora = Panora(
            api_key=os.getenv("API_KEY", ""),
        )

        res = panora.webhooks.create(request={
            "url": "https://acme.com/webhook_receiver",
            "scope": [
                "connection.created",
            ],
        })
        ```
        </CodeGroup>

    </Step>
    <Step title="Secure your webhook endpoint.">
        We highly recommend you secure your integration by ensuring your handler verifies that all webhook requests are generated by Panora. You can choose to verify webhook signatures using our official libraries or verify them manually.<br/>

        **Verify webhook signatures with official library** <br/>

        We recommend using our official libraries to verify signatures. You perform the verification by providing the event payload, the `Panora-Signature` header, and the endpoint’s secret. If verification fails, you get an error.

        <CodeGroup>
        ```javascript Node
        import express, { Request, Response } from 'express';
        import { Panora } from '@panora/sdk';

        type ConnectionData = {
            connection_token: string;
            provider_slug: string;
            vertical: string;
            [key: string]: any;
        }

        // Set your api key
        // See your keys here: https://app.panora.dev/api-keys
        const panora = new Panora({ apiKey: process.env.API_KEY });

        // Find your endpoint's secret in your webhook settings in the Config Page
        const endpointSecret = 'whsec_...';

        // This example uses Express to receive webhooks
        const app = express();

        app.use(express.json());

        // Match the raw body to content type application/json
        app.post('/webhook', async (request, response) => {
            const sig = request.headers['panora-signature'];

            let event: Record<string, any> = {};

            try {
                // Verifies that the event comes from Panora and not from malicious sender
                event = await panora.webhooks.verifyEvent({
                    payload: request.body,
                    signature: sig as any,
                    secret: endpointSecret,
                });
            }
            catch (err) {
                response.status(400).send(`Webhook Error: ${(err as any).message}`);
            }

            // Handle the event
            switch (event.type) {
                case 'connection.created':
                    const connectionData: ConnectionData = JSON.parse(event.data);
                    console.log(`Received connectionToken data ${JSON.stringify(connectionData)}`)
                    break;
                case 'filestorage.file.pulled':
                    console.log(`Retrieving files...`)
                    const files = event.data;
                    console.log(JSON.stringify(files))
                    /*Alternatively you can use our SDK with your connectionToken to retireve the same data
                    
                    const result = await panora.filestorage.files.list({
                        xConnectionToken: connectionToken,
                        remoteData: true,
                    });
                    for await (const page of result) {
                        console.log(`Files are ${JSON.stringify(page.result)}`)
                    }*/
                    break;
                default:
                    console.log(`Unhandled event type ${event.type}`);
            }
            // Return a response to acknowledge receipt of the event
            response.json('Received !');

        });

        app.listen(8080, () => console.log('Running on port 8080'));
        ```


        ```python Python
        import os
        import json
        from panora_sdk import Panora
        from django.http import HttpResponse
        from django.views.decorators.csrf import csrf_exempt
        from django.views.decorators.http import require_http_methods

        # Set your api key
        # See your keys here: https://app.panora.dev/api-keys
        panora = Panora(api_key=os.getenv("API_KEY", ""))

        # Find your endpoint's secret in your webhook settings in the Config Page
        endpoint_secret = 'whsec_...'

        connection_token = ''

        @csrf_exempt
        @require_http_methods(["POST"])
        def my_webhook_view(request):
            payload = request.body
            sig_header = request.headers.get('panora-signature')

            try:
                # Verifies that the event comes from Panora and not from malicious sender
                event = panora.webhooks.verify_event(request={
                    "payload": payload,
                    "signature": sig_header,
                    "secret": endpoint_secret,
                })
            except ValueError as e:
                # Invalid payload
                return HttpResponse(f"Webhook Error: {str(e)}", status=400)

            # Handle the event
            event_type = event.get('type')
            if event_type == 'connection.created':
                connection_data = json.loads(event['data'])
                connection_token = connection_data.get('connection_token')
                print(f"Received connectionToken data {json.dumps(connection_data)}")
            elif event_type == 'filestorage.file.pulled':
                print("Retrieving files...")
                files = event['data']
                print(json.dumps(files))
                """Alternatively you can use our SDK with your connectionToken to retrieve the same data
                
                result = panora.filestorage.files.list(
                    x_connection_token=connection_token,
                    remote_data=True
                )
                for page in result:
                    print(f"Files are {json.dumps(page.result)}")
                """
            else:
                print(f"Unhandled event type {event_type}")

            # Return a response to acknowledge receipt of the event
            return HttpResponse('Received !')
        ```
        </CodeGroup>

    </Step>

</Steps>
